package com.zdy.im.user.service.impl;


import com.sixeco.framework.common.data.BasePage;
import com.sixeco.framework.common.enums.ResultEnum;
import com.sixeco.framework.core.db.ext.Query;
import com.sixeco.framework.http.data.vo.ResponseResultList;
import com.sixeco.framework.util.PageUtils;
import com.sixeco.framework.util.excel.ExcelUtils;
import com.zdy.im.enums.ImMessageTypeEnum;
import com.zdy.im.user.service.ImMessageReadService;
import com.zdy.im.user.dto.response.ImMessageReadResponseDto;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.io.InputStream;


import com.zdy.im.user.entity.ImMessageRead;
import com.zdy.im.user.dao.ImMessageReadDao;
import com.zdy.im.user.dto.request.ImMessageReadRequestDto;


/**
 * @ClassName: ImMessageReadDao.java
 * @Description: 消息状态表的数据交互处理类
 * @author x
 * @date   2021-05-24 20:29:06
 * @version V1.0.0
 * <p>
 * ----------------------------------------------------------------------------
 *  modifyer    modifyTime                 comment
 *
 * ----------------------------------------------------------------------------
 * </p>
 */
@Service
public class ImMessageReadServiceImpl  implements ImMessageReadService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ImMessageReadDao  imMessageReadDao;



    /**
     * 保存消息状态表同时更新数据库和缓存的实现方法
     * @param imMessageReadRequestDto ImMessageReadResponseDto
     * @return
     */
    public ImMessageReadResponseDto saveImMessageRead(ImMessageReadRequestDto imMessageReadRequestDto){
        if(imMessageReadRequestDto== null){
            return null;
        }
        ImMessageRead imMessageRead = ImMessageRead.build().clone(imMessageReadRequestDto);
        boolean result = imMessageReadDao.save(imMessageRead);
        if(!result){
            return null;
        }
        ImMessageReadResponseDto imMessageReadResponseDto = ImMessageReadResponseDto.build().clone(imMessageRead);
        return imMessageReadResponseDto;


    }

    public boolean saveBatchImMessageRead(Collection<ImMessageReadRequestDto> entityList, int batchSize) {
        if(null == entityList || entityList.size() !=  batchSize){
            return false;
        }
        List<ImMessageRead> list = new ArrayList<>();
        entityList.forEach(e -> list.add(ImMessageRead.build().clone(e)));
        boolean result = imMessageReadDao.saveBatch(list,batchSize);
        return result;
    }


    public boolean saveOrUpdateBatchImMessageRead(Collection<ImMessageReadRequestDto> entityList, int batchSize) {
        if(null == entityList || entityList.size() != batchSize ){
            return false;
        }
        List<ImMessageRead> list = new ArrayList<>();
        entityList.forEach(e -> list.add(ImMessageRead.build().clone(e)));
        boolean result = imMessageReadDao.saveOrUpdateBatch(list,batchSize);
        return result;
    }


    public boolean updateBatchById(Collection<ImMessageReadRequestDto> entityList, int batchSize) {
        if(null == entityList || entityList.size() != batchSize ){
            return false;
        }
        List<ImMessageRead> list = new ArrayList<>();
        entityList.forEach(e -> list.add(ImMessageRead.build().clone(e)));
        boolean result =  imMessageReadDao.updateBatchById(list,batchSize);
        return result;
    }

    /**
     * 更新消息状态表同时更新数据库和缓存的实现方法
     * @param imMessageReadRequestDto  ImMessageReadResponseDto
     * @return
     */
    public boolean updateImMessageRead(ImMessageReadRequestDto imMessageReadRequestDto){

          if(null ==  imMessageReadRequestDto){
              return false;
          }

        ImMessageRead imMessageRead = ImMessageRead.build().clone(imMessageReadRequestDto);

        return imMessageReadDao.updateById(imMessageRead);


    }







    /**
     * 通过主键ID删除对象信息实现缓存和数据库,同时删除的方法
     * @param  idList
     * @return
     */
    public int delImMessageReadByIds(List<Long> idList){
        boolean result = false;
        if(null == idList){
            return ResultEnum.FAIL.id();
        }
        if( idList.size() == 1) {
            result = imMessageReadDao.removeById(idList.get(0));
        }else {
            result =  imMessageReadDao.removeByIds(idList);
        }
        if(result){
            return ResultEnum.SUCCESS.id();
        }
        return ResultEnum.FAIL.id();

    }


    /**
     * 通过主键ID更新对象消息状态表实现缓存和数据库更新的方法
     * @param  imMessageReadId
     * @return
     */
    public ImMessageReadResponseDto getImMessageReadById(long imMessageReadId){
        if(imMessageReadId < 0 ){
            return null;
        }
        ImMessageRead imMessageRead =  imMessageReadDao.getById(imMessageReadId);
        if(imMessageRead == null){
            return null;
        }
        ImMessageReadResponseDto imMessageReadResponseDto = ImMessageReadResponseDto.build().clone(imMessageRead);

        return imMessageReadResponseDto ;

    }

    @Override
    public List<ImMessageReadResponseDto> getImMessageReadByPage(BasePage page) {
        return null;
    }


    /**
    * 查询条件
    */
    public QueryWrapper<ImMessageRead> checkQueryCondition(BasePage basePage) {
        QueryWrapper<ImMessageRead> queryWrapper = new QueryWrapper<>();
        ImMessageReadRequestDto imMessageReadRequestDto = (ImMessageReadRequestDto) basePage.getParamObject();

                                                                                                return queryWrapper;
    }


    /**
     * 通过分页获取ImMessageRead信息实现查找缓存和数据库的方法
     * @param basePage BasePage
     * @return
     * @author x
     * @date 2021-05-24 20:29:06
     */
    public List<ImMessageReadResponseDto> getImMessageReadByPage(
            ResponseResultList<ImMessageReadResponseDto> responseResultList, BasePage basePage){


        List<ImMessageReadResponseDto> resDtoList = new ArrayList<>();
        if(basePage == null){
            return resDtoList;
        }
        //分页对象        PageHelper
        IPage<ImMessageRead> iPage = new Page<>(basePage.getPageNo(), basePage.getRealPageSize());
        QueryWrapper<ImMessageRead> queryWrapper = checkQueryCondition(basePage);

        IPage<ImMessageRead> page = imMessageReadDao.page(iPage, queryWrapper);
        if(null == page){
            return resDtoList;
        }

        List<ImMessageRead>  list = page.getRecords();
        if(null == list || list.isEmpty()){
            return resDtoList;
        }
        list.forEach(imMessageRead -> {
                ImMessageReadResponseDto imMessageReadResponseDto = ImMessageReadResponseDto.build().clone(imMessageRead);

            resDtoList.add(imMessageReadResponseDto);
        });
        responseResultList.setTotal((int) page.getTotal());
        return resDtoList;


    }

    /**
     * 通过分页获取ImMessageRead信息实现查找缓存和数据库的方法
     * @param basePage BasePage
     * @return
     * @author x
     * @date 2021-05-24 20:29:06
     */
    public ResponseResultList<ImMessageReadResponseDto> getImMessageReadByNextPage(BasePage basePage){
        ResponseResultList<ImMessageReadResponseDto> responseResultList = ResponseResultList.build();
        List<ImMessageReadResponseDto>  list = this.getImMessageReadByPage(responseResultList,basePage);
        if(null == list ){
            list = new ArrayList<>();
        }
        boolean isNext =  basePage.isNextPage(list);
        responseResultList.toIsNextPage(isNext).toList(list);
        return responseResultList;

    }

    public PageUtils queryPage(Map<String, Object> params) {
        IPage iPage =  new Query<ImMessageRead>().getPage(params);
        QueryWrapper<ImMessageRead> queryWrapper = new QueryWrapper<>();
        IPage<ImMessageRead> page = imMessageReadDao.page(iPage,queryWrapper);
        return new PageUtils(page);
    }


    /**
     * 保存消息状态表同时更新数据库和缓存的实现方法
     * @return
     */
    public ImMessageRead  setImMessageRead(){
        ImMessageRead imMessageRead = new ImMessageRead();
        /**
 			//imMessageRead.setUserId (long userId);
 			//imMessageRead.setMessageId (long messageId);
 			//imMessageRead.setGlobalId (long globalId);
 			//imMessageRead.setType (int type);
		**/

        return imMessageRead;
    }

    public boolean saveData(InputStream initialStream) {
        return ExcelUtils.readExcel(initialStream,imMessageReadDao, ImMessageRead.class,0);
    }

    @Override
    public ImMessageReadResponseDto getImMessageReadByUser(ImMessageReadRequestDto im) {
        ImMessageRead imMessageRead =  imMessageReadDao.getImMessageReadByUser(im);
        if(imMessageRead == null){
            return null;
        }
        ImMessageReadResponseDto imMessageReadResponseDto = ImMessageReadResponseDto.build().clone(imMessageRead);

        return imMessageReadResponseDto ;
    }

    @Override
    public Map<Integer, Map<Long, Long>> getImMessageReadMapByUserId(long userId) {
        Map<Integer, Map<Long, Long>> map = new HashMap<>();
        List<ImMessageRead> imMessageReadList =  imMessageReadDao.getImMessageReadMapByUserId(userId);
        if(imMessageReadList == null){
            return map;
        }
        Map<Long, Long> userMap = new HashMap<>();
        Map<Long, Long> groupMap = new HashMap<>();
        imMessageReadList.stream().forEach( read ->{
            if(read.getType() == ImMessageTypeEnum.Single.getKey()){
                userMap.put(read.getMessageId() , read.getGlobalId());
            }else{
                groupMap.put(read.getMessageId() , read.getGlobalId());
            }
        });
        map.put(ImMessageTypeEnum.Single.getKey() ,userMap);
        map.put(ImMessageTypeEnum.Group.getKey() ,groupMap);
        return map ;
    }


}
